package com.yorkfeng.blemulti.Activity;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.yorkfeng.blemulti.R;
import com.yorkfeng.blemulti.Service.BluetoothLeService;
import com.yorkfeng.blemulti.Utils.Constants;
import com.yorkfeng.blemulti.Utils.CustomToast;

import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    public static final String TAG = MainActivity.class.getSimpleName();

    private BluetoothAdapter mBluetoothAdapter;
    private static final int REQUEST_ENABLE_BT = 1;
    private BluetoothLeService mBluetoothLeService;

    private BluetoothGattCharacteristic sendCharacteristicL, sendCharacteristicR;
    private BluetoothGattCharacteristic readCharacteristicL, readCharacteristicR;
    private String mDeviceNameLeft, mDeviceNameRight;
    private String mDeviceAddressLeft, mDeviceAddressRight;
    private TextView mTitleL, mTitleR, tvReadL, tvReadR;
    private boolean mConnectedLeft = false;
    private boolean mConnectedRight = false;
    private boolean isInitSuccessL = false;
    private boolean isInitSuccessR = false;
    private boolean isBroadcast = false;

    private final Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 检查当前手机是否支持ble 蓝牙,如果不支持退出程序
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            CustomToast.showToast(getBaseContext(), "BLE is not supported", 1000);
            finish();
        }

        // 初始化 Bluetooth adapter, 通过蓝牙管理器得到一个参考蓝牙适配器(API必须在以上android4.3或以上和版本)
        final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

        // 检查设备上是否支持蓝牙
        if (mBluetoothAdapter == null) {
            CustomToast.showToast(getBaseContext(), "Bluetooth not supported", 1000);
            finish();
            return;
        }

        // 为了确保设备上蓝牙能使用, 如果当前蓝牙设备没启用,弹出对话框向用户要求授予权限来启用
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }

        // 从内存中取出参数值赋给全局变量
        SharedPreferences pres = MainActivity.this.getSharedPreferences(Constants.CONFIG_FILE_NAME,
                Context.MODE_PRIVATE);

        if (!isBroadcast) {
            // 注册广播
            registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
            isBroadcast = true;
            Log.d(TAG, "注册广播");
        }

        // 显示已经连接的蓝牙设备名
        mTitleL = (TextView) findViewById(R.id.tv_name_l);
        tvReadL = (TextView) findViewById(R.id.tv_data_l);

        mTitleR = (TextView) findViewById(R.id.tv_name_r);
        tvReadR = (TextView) findViewById(R.id.tv_data_r);

        tvReadL.setMovementMethod(ScrollingMovementMethod.getInstance());
        tvReadR.setMovementMethod(ScrollingMovementMethod.getInstance());

        findViewById(R.id.btn_scan_l).setOnClickListener(this);
        findViewById(R.id.btn_scan_r).setOnClickListener(this);
        findViewById(R.id.btn_send_l).setOnClickListener(this);
        findViewById(R.id.btn_send_r).setOnClickListener(this);
        findViewById(R.id.btn_clear_l).setOnClickListener(this);
        findViewById(R.id.btn_clear_r).setOnClickListener(this);
    }

    // Code to manage Service lifecycle.
    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            // Automatically connects to the device upon successful start-up
            // initialization.
            Log.d(TAG, "service 绑定成功");
            if (mDeviceAddressLeft.length() != 0) {
                mBluetoothLeService.connect(mDeviceAddressLeft, 0);
            }
            if (mDeviceAddressRight.length() != 0) {
                mBluetoothLeService.connect(mDeviceAddressRight, 1);
            }
        }

        @Override
        // 类ServiceConnection中的onServiceDisconnected()方法在正常情况下是不被调用的，
        // 它的调用时机是当Service服务被异外销毁时，例如内存的资源不足时这个方法才被自动调用
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG, "onServiceDisconnected");
            if (null != mBluetoothLeService) {
                mBluetoothLeService = null;
            }
        }
    };

    // Handles various events fired by the Service.
    // ACTION_GATT_CONNECTED: connected to a GATT server.
    // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
    // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
    // ACTION_DATA_AVAILABLE: received data from the device. This can be a
    // result of read
    // or notification operations.
    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            Log.d(TAG, "action = " + action);
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                int gatt = intent.getIntExtra("GATT", 100);
                if (gatt == 0){
                    mConnectedLeft = true;
                    updateConnectionState(mConnectedLeft, 0);
                }else if (gatt == 1) {
                    mConnectedRight = true;
                    updateConnectionState(mConnectedRight, 1);
                }

            }
            // 蓝牙断开
            else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                int gatt = intent.getIntExtra("GATT", 100);

                if (gatt == 0) {
                    mConnectedLeft = false;
                    updateConnectionState(mConnectedLeft, 0);
                    isInitSuccessL = false;
                    sendCharacteristicL = null;
                    readCharacteristicL = null;
                    CustomToast.showToast(getBaseContext(), "Disconnected", 1000);
                }else if (gatt == 1) {
                    mConnectedRight = false;
                    updateConnectionState(mConnectedRight, 1);
                    isInitSuccessR = false;
                    sendCharacteristicR = null;
                    readCharacteristicR = null;
                    CustomToast.showToast(getBaseContext(), "Disconnected", 1000);
                }

            }
            // 请重启蓝牙
            else if (BluetoothLeService.ACTION_GATT_UNCONNECTED.equals(action))   {
                CustomToast.showToast(getBaseContext(), "There may be a problem with Bluetooth", 1000);
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                // Show all the supported services and characteristics on the
                // user interface.
                int gatt = intent.getIntExtra("GATT", 100);

                try {
                    if (null == mBluetoothLeService) {
                        Log.e(TAG, "null == mBluetoothLeService");
                    }
                    displayGattServices(mBluetoothLeService.getSupportedGattServices(gatt), gatt);
                } catch (Exception e) {
                    Log.e(TAG, e.toString());
                }

            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                byte[] data = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);

                int gatt = intent.getIntExtra("GATT", 100);

                if (gatt == 0){
                    System.out.println("--------read l success----- data:" + data);
                    final StringBuilder stringBuilder = new StringBuilder(data.length);
                    for (byte byteChar : data) {
                        stringBuilder.append(String.format("%02X ", byteChar));
                    }
                    tvReadL.setText(tvReadL.getText() + "\n" + stringBuilder.toString());
                } else if (gatt == 1) {
                    System.out.println("--------read r success----- data:" + data);
                    final StringBuilder stringBuilder = new StringBuilder(data.length);
                    for (byte byteChar : data) {
                        stringBuilder.append(String.format("%02X ", byteChar));
                    }
                    tvReadR.setText(tvReadR.getText() + "\n" + stringBuilder.toString());
                }
            }
            // 屏幕熄灭，蓝牙连接关闭
            else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                Log.d(TAG, "屏幕熄灭或者跳转到主页，关闭蓝牙连接");
                disconnectBluetooth();
            }
        }
    };

    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_UNCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        // intentFilter.addAction(BluetoothLeService.ACTION_GATT_INIT_SUCCESS);
        // intentFilter.addAction(BluetoothLeService.ACTION_GATT_INIT_FAILURE);
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        return intentFilter;
    }

    public boolean isInit(int gatt) {
        if (gatt == 0){
            if (null == sendCharacteristicL || null == readCharacteristicL || !isInitSuccessL) {
                // 初始化失败，蓝牙断开
                mBluetoothLeService.disconnect(0);
                return false;
            }
        } else if (gatt == 1) {
            if (null == sendCharacteristicR || null == readCharacteristicR || !isInitSuccessR) {
                // 初始化失败，蓝牙断开
                mBluetoothLeService.disconnect(1);
                return false;
            }
        }

        return true;
    }

    // Demonstrates how to iterate through the supported GATT
    // Services/Characteristics.
    // In this sample, we populate the data structure that is bound to the
    // ExpandableListView
    // on the UI.
    private void displayGattServices(List<BluetoothGattService> gattServices, int gatt) {
        if (gattServices == null) {
            return;
        }
        String uuid = null;

        if (gatt == 0) {
            // Loops through available GATT Services.
            for (BluetoothGattService gattService : gattServices) {
                uuid = gattService.getUuid().toString();
                // 没有值
                List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();

                // Loops through available Characteristics.
                for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                    uuid = gattCharacteristic.getUuid().toString();

                    System.out.println("-=-=-=-=-=-=-=-  " + uuid);

                    // 初始化
                    if (Constants.UUID_READ_CHARACTERISTIC.equals(uuid)) {
                        readCharacteristicL = gattCharacteristic;
                        // 读取返回的状态
                        mBluetoothLeService.setCharacteristicNotification(readCharacteristicL, true, 0);
                    } else if (Constants.UUID_SEND_CHARACTERISTIC.equals(uuid)) {
                        sendCharacteristicL = gattCharacteristic;
                    }
                }
            }
            // 初始化成功
            if (null != readCharacteristicL && null != sendCharacteristicL) {
                isInitSuccessL = true;
                CustomToast.showToast(getBaseContext(), "Connected success.", 1000);
            }

        }else if (gatt == 1) {
            // Loops through available GATT Services.
            for (BluetoothGattService gattService : gattServices) {
                uuid = gattService.getUuid().toString();
                // 没有值
                List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();

                // Loops through available Characteristics.
                for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                    uuid = gattCharacteristic.getUuid().toString();

                    System.out.println("-=-=-=-=-=-=-=-  " + uuid);

                    // 初始化
                    if (Constants.UUID_READ_CHARACTERISTIC.equals(uuid)) {
                        readCharacteristicR = gattCharacteristic;
                        // 读取返回的状态
                        mBluetoothLeService.setCharacteristicNotification(readCharacteristicR, true, 1);
                    } else if (Constants.UUID_SEND_CHARACTERISTIC.equals(uuid)) {
                        sendCharacteristicR = gattCharacteristic;
                    }
                }
            }
            // 初始化成功
            if (null != readCharacteristicR && null != sendCharacteristicR) {
                isInitSuccessR = true;
                CustomToast.showToast(getBaseContext(), "Connected success.", 1000);
            }

        }
    }

    private void updateConnectionState(final boolean connected, final int gatt) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (gatt == 0) {
                    if (connected) {
                        // 从内存中取得最新的设备名
                        SharedPreferences pres = MainActivity.this.getSharedPreferences(Constants.CONFIG_FILE_NAME,
                                Context.MODE_PRIVATE);

                        Map<String, ?> allContent1 = pres.getAll();
                        String content = new String();
                        // 注意遍历map的方法
                        for (Map.Entry<String, ?> entry : allContent1.entrySet()) {
                            content += (entry.getKey() + entry.getValue());
                        }
                        Log.d(TAG, content);

                        mDeviceNameLeft = pres.getString(mDeviceAddressLeft, "");
                        mTitleL.setText(mDeviceNameLeft);
                    } else {
                        mTitleL.setText("");
                    }
                } else if (gatt == 1) {
                    if (connected) {
                        // 从内存中取得最新的设备名
                        SharedPreferences pres = MainActivity.this.getSharedPreferences(Constants.CONFIG_FILE_NAME,
                                Context.MODE_PRIVATE);

                        Map<String, ?> allContent1 = pres.getAll();
                        String content = new String();
                        // 注意遍历map的方法
                        for (Map.Entry<String, ?> entry : allContent1.entrySet())
                        {
                            content += (entry.getKey() + entry.getValue());
                        }
                        Log.d(TAG, content);

                        mDeviceNameRight = pres.getString(mDeviceAddressRight, "");
                        mTitleR.setText(mDeviceNameRight);
                    } else {
                        mTitleR.setText("");
                    }
                }

            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
        // 根据设置调整布局

        autoConnectedBluetooth();
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "-=-=-=-=-onStop");

        // 跳转到设置界面，蓝牙连接不断开
        if (!Constants.isTopActivity(getApplicationContext(), Constants.MAIN_ACTIVITY)
                && !Constants.isTopActivity(getApplicationContext(), Constants.SEARCH_ACTIVITY)) {
            disconnectBluetooth();
        }
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();

        // 判断是否已经注销
        try {
            unregisterReceiver(mGattUpdateReceiver);
            isBroadcast = false;
        }
        catch (Exception e) {
            Log.e(TAG, "注销广播");
        }
    }

    public void autoConnectedBluetooth() {
        // 检查蓝牙有没有打开
        if (!mBluetoothAdapter.isEnabled()) {
            CustomToast.showToast(getBaseContext(), "Please activate Bluetooth", 1000);
            return;
        }
        // 未连接时
        if (!mConnectedLeft) {
            // 未连接设备
            CustomToast.showToast(getBaseContext(), "No device connected", 1000);

            // 从内存中取出参数值，重新连接
            SharedPreferences pres = MainActivity.this.getSharedPreferences(Constants.CONFIG_FILE_NAME,
                    Context.MODE_PRIVATE);
            mDeviceAddressLeft = pres.getString(Constants.LAST_CONNECTED_ADDRESS_L, "");
            Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
            // bindService是异步调用和Service进行绑定, 如果绑定成功,
            // 则会调用ServiceConnection的onServiceConnected
            boolean bll = bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

            if (bll) {
                Log.d(TAG, "---------------");
            } else {
                Log.d(TAG, "===============");
            }

            registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());

            // 连接设备
            if (mBluetoothLeService != null && mDeviceAddressLeft.length() != 0) {
                final boolean result = mBluetoothLeService.connect(mDeviceAddressLeft, 0);
                Log.d(TAG, "Connect request result=" + result);
            }
        }
        if (!mConnectedRight) {
            // 未连接设备
            CustomToast.showToast(getBaseContext(), "No device connected", 1000);

            // 从内存中取出参数值，重新连接
            SharedPreferences pres = MainActivity.this.getSharedPreferences(Constants.CONFIG_FILE_NAME,
                    Context.MODE_PRIVATE);
            mDeviceAddressRight = pres.getString(Constants.LAST_CONNECTED_ADDRESS_R, "");
            Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
            // bindService是异步调用和Service进行绑定, 如果绑定成功,
            // 则会调用ServiceConnection的onServiceConnected
            boolean bll = bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

            if (bll) {
                Log.d(TAG, "---------------");
            } else {
                Log.d(TAG, "===============");
            }

            registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());

            // 连接设备
            if (mBluetoothLeService != null && mDeviceAddressRight.length() != 0) {
                final boolean result = mBluetoothLeService.connect(mDeviceAddressRight, 1);
                Log.d(TAG, "Connect request result=" + result);
            }
        }

    }

    // 关闭蓝牙连接
    public void disconnectBluetooth() {
        try {
            if (mConnectedLeft && null != mBluetoothLeService) {
                mBluetoothLeService.disconnect(0);
                // 已经注销
                mConnectedLeft = false;
                updateConnectionState(mConnectedLeft, 0);
            }
            if (mConnectedRight && null != mBluetoothLeService) {
                mBluetoothLeService.disconnect(1);
                // 已经注销
                mConnectedRight = false;
                updateConnectionState(mConnectedRight, 1);
            }

            if (null != mBluetoothLeService) {
                Log.d(TAG, "解除" + mBluetoothLeService.toString());
                // 检查服务是否还绑定,解除绑定
                unbindService(mServiceConnection);
                if (null != mBluetoothLeService) {
                    mBluetoothLeService = null;
                }

            }

        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }

    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this, BluetoothSearchActivity.class);

        byte[] Byte = new byte[8];

        Byte[0] = 0xA5-0x100;
        Byte[1] = 0xC7-0x100;
        Byte[2] = 0x11;
        Byte[3] = 0x00;
        Byte[4] = 0x00;
        Byte[5] = 0x00;
        Byte[6] = 0x00;
        Byte[7] = 0x82-0x100;

        switch (v.getId()) {
            case R.id.btn_scan_l:
                intent.putExtra("GATT", 0);
                startActivity(intent);
                break;

            case R.id.btn_scan_r:
                intent.putExtra("GATT", 1);
                startActivity(intent);
                break;

            case R.id.btn_send_l:
                sendCharacteristicL.setValue(Byte);
                mBluetoothLeService.wirteCharacteristic(sendCharacteristicL, 0);
                break;

            case R.id.btn_send_r:
                sendCharacteristicR.setValue(Byte);
                mBluetoothLeService.wirteCharacteristic(sendCharacteristicR, 1);
                break;

            case R.id.btn_clear_l:
                tvReadL.setText("");
                break;

            case R.id.btn_clear_r:
                tvReadR.setText("");
                break;

            default:
                break;
        }
    }
}
